package com.papper.common.config;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.papper.common.bean.sys.SysConfig;
import com.papper.common.bean.sys.SysSystem;
import com.papper.common.service.sys.SysConfigService;
import com.papper.common.service.sys.SysSystemService;
import com.papper.common.utils.PapperSpringUtil;
import com.papper.common.utils.tool.StringTool;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author:LaJiao
 * @date 2022年04月10日
 * @time 08时16
 * @Description:本地缓存配置信息
 */
public class PapperStorage {
    private final static Logger              logger           = LoggerFactory.getLogger(PapperStorage.class);
    private static       Map<String, String> LocalConfigInfo  = Maps.newHashMap();
    private static       Map<String, String> SysConfigInfo    = Maps.newHashMap();
    private static       SysSystem           systemInfo       = null;
    private static       JSONObject          SystemConfigInfo = null;
    private final static List<String>        LocalConfigPath  = Lists.newArrayList("classpath:config.xml", "file:config.xml");

    static {
        initLocalConfig();
        initSysConfig();
        initSystemInfo();
    }

    public static void initStorage(List<String> storage) {
        if (storage == null) {
            return;
        }
        if (storage.contains("Local")) {
            initLocalConfig();
        }
        if (storage.contains("Config")) {
            initSysConfig();
        }
        if (storage.contains("System")) {
            initSystemInfo();
        }
    }

    private static void initLocalConfig() {
        logger.info("加载系统本地配置文件:[{}]", LocalConfigPath);
        LocalConfigInfo.clear();
        LocalConfigPath.forEach(path -> {
            try {
                ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
                Resource                resource = resolver.getResource(path);
                if (resource.exists()) {
                    logger.info("加载本地配置信息:[{}]", path);
                    InputStream       fis      = resource.getInputStream();
                    InputStreamReader isr      = new InputStreamReader(fis, StandardCharsets.UTF_8);
                    SAXReader         reader   = new SAXReader();
                    Document          document = reader.read(isr);
                    List<Element>     lstPropS = document.getRootElement().elements("props");
                    for (Element props : lstPropS) {
                        List<Element> lstProp = props.elements("prop");
                        for (Element prop : lstProp) {
                            LocalConfigInfo.put(prop.attributeValue("key"), prop.getTextTrim());
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("读取配置异常[{}]:{}", path, e.getMessage());
            }
        });
    }

    private static void initSysConfig() {
        logger.info("加载系统配置信息:[SysConfig]");
        SysConfigInfo.clear();
        try {
            // 系统配置
            SysConfigService s           = (SysConfigService) PapperSpringUtil.getBean("sysConfigService");
            List<SysConfig>  lstProperty = s.findAll();
            if (lstProperty != null && !lstProperty.isEmpty()) {
                Map<Long, String> topKey = Maps.newHashMap();
                for (SysConfig p : lstProperty) {
                    topKey.put(p.getId(), p.getCodeKey());
                }
                String key   = null;
                String value = null;
                for (SysConfig p : lstProperty) {
                    if (p.getParentId().intValue() == 0) {
                        continue;
                    }
                    key = StringTool.nullToEmpty(topKey.get(p.getParentId().longValue())) + "." + p.getCodeKey();
                    value = p.getCodeValue();
                    SysConfigInfo.put(key, value);
                }
            }
        } catch (Exception ex) {
            logger.error("读取配置异常[SysConfig]:{}", ex.getMessage());
        }
    }

    private static void initSystemInfo() {
        logger.info("加载系统信息:[SysSystem]");
        try {
            SysSystemService sysSystemService = (SysSystemService) PapperSpringUtil.getBean("sysSystemService");
            systemInfo = sysSystemService.findSysSystem();
            if (systemInfo != null) {
                SystemConfigInfo = JSONObject.parseObject(systemInfo.getSystemDesc());
            } else {
                systemInfo = new SysSystem();
                systemInfo.setSystemCode(LocalConfigInfo.get(StorageConstants.SYSTEM_CODE));
                systemInfo.setSystemName(LocalConfigInfo.get(StorageConstants.SYSTEM_NAME));
                SystemConfigInfo = new JSONObject();
            }
        } catch (Exception ex) {
            logger.error("读取配置异常[SysSystem]:{}", ex.getMessage());
        }
    }

    /**
     * 获取本地配置信息值
     */
    public static String Local(String key, String def) {
        return Optional.ofNullable(LocalConfigInfo).map(item -> item.get(key)).orElse(def);
    }

    public static String Local(String key) {
        return Optional.ofNullable(LocalConfigInfo).map(item -> item.get(key)).orElse(StringTool.EMPTY);
    }

    /**
     * 获取启动系统信息
     */
    public static SysSystem System() {
        return systemInfo;
    }

    public static String SystemConfig(String key) {
        return Optional.ofNullable(SystemConfigInfo).map(item -> item.getString(key)).orElse(StringTool.EMPTY);
    }

    /**
     * 获取系统配置信息
     */
    public static String Config(String tk, String k, String def) {
        String key = tk + "." + k;
        return Config(key, def);
    }

    public static String Config(String key, String def) {
        return Optional.ofNullable(SysConfigInfo).map(item -> item.get(key)).orElse(def);
    }
}
